;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

INCLUDE "gbhw.inc"          ; import file definitions

;Variables
_NUMBER EQU _RAM

; Constants
_POS_CRONOM         EQU     _SCRN0+32*4+6   ; screen position

; VBlank interruption
SECTION "Vblank",HOME[$0040]
    call DrawingNumbers
    reti
    
; The program begins here:
SECTION "start",HOME[$0100]
    nop
    jp      start
    
    ROM_HEADER  ROM_NOMBC, ROM_SIZE_32KBYTE, RAM_SIZE_0KBYTE
    
start:
    nop
    di                      ; disables interrupts
    ld      sp, $ffff       ; We aim pile atop the ram initialization:

init:
    ;set Variables
    ld a, 0
    ld [_NUMBER], a
    
    ld      a, %11100100	; Pallet
    ld      [rBGP], a		; write background pallet
    ld      [rOBP0], a		; write sprite pallet
    ld	    a, 0
    ld      [rSCX], a
    ld      [rSCY], a
    
    call    Shutdown_LCD       	; turn off LCD
    
    ; Load Tiles into memory
    
    ld hl, Tiles
    ld      de, _VRAM
    ld      bc, FinTiles-Tiles  ; number of bytes to copy
    
    call CopyMemory
    
    ;clean map
    ld      de, _SCRN0      ; map 0
    ld      bc, 32*32
    ld      l, 11           ; empty tile
    call    FillMemory
    
    ; sprite attribute memory
    ld      de, _OAMRAM     ; sprite attribute memory
    ld      bc, 40*4        ;  40 sprites x 4 bytes each
    ld      l, 0            ; we will start fresh, so the sprites
    call    FillMemory  ; Unused remain off-screen
    
    call     DrawingNumbers ; Draw stopwatch
    
    ; setup and activate display
    ld      a, LCDCF_ON|LCDCF_BG8000|LCDCF_BG9800|LCDCF_BGON|LCDCF_OBJ8
    ld      [rLCDC], a
    
; main loop
main:

ld  bc, 15000
call delay

call WaitVBlank

call DrawingNumbers

call IncrementNumber

cp 9

jr z, ResetNumber

jr main
    
IncrementNumber:

    ld a, [_NUMBER]
    inc a
    ld [_NUMBER], a
    
    ret
    
ResetNumber:
ld a, 0
ret
    
DrawingNumbers:
    
    ld a, [_NUMBER]
    ld [_POS_CRONOM], a
    
    ret
    
; LCD shutdown routine
Shutdown_LCD:
    ld      a,[rLCDC]
    rlca                    ;It sets the high bit of LCDC in the carry flag
    ret     nc              ; Display is already off, again.
 
    ; We VBlank hope to, because we can not turn off the screen
    ; some other time
    call    WaitVBlank
 
    ; we are in VBlank, we turn off the LCD
    ld      a,[rLCDC]       ; in A, the contents of the LCDC
    res     7,a             ; we zero bit 7 (on the LCD)
    ld      [rLCDC],a       ; We wrote in the LCDC register content A
 
    ret                     ; return
    
WaitVBlank:
    ld      a, [rLY]
    cp      145
    jr      nz, WaitVBlank
    ret
  
delay:
.delay:
    dec     bc              ; decrement
    ld      a, b            ; see if zero
    or      c
    jr      z, .fin_delay
    nop
    jr      .delay
.fin_delay:
    ret
  
; memory copy routine
; copy a number of bytes from one direction to another
; expects the parameters:
; hl - copying data address
; of - destination address
; bc - amount of data to be copied
; destroys the contents of A

CopyMemory:
    ld      a, [hl]     ; To load the data in A
    ld      [de], a     ; copy the data to the destination
    dec     bc          ; least one copy
    ; We check if bc is zero
    ld      a, c
    or      b
    ret     z           ; If zero, we return
    ; if not, we still
    inc     hl
    inc     de
    jr      CopyMemory

FillMemory:
    ld      a, l
    ld      [de], a     ; puts the data in the destination
    dec     bc          ; least one fill
 
    ld      a, c
    or      b           ; We check if bc is zero
    ret     z           ; If zero return
    inc     de          ; if not, we still
    jr      FillMemory
  
Tiles:
; 0
DW  `00000000
DW  `00333300
DW  `03000330
DW  `03003030
DW  `03030030
DW  `03300030
DW  `00333300
DW  `00000000
; 1
DW  `00000000
DW  `00003000
DW  `00033000
DW  `00003000
DW  `00003000
DW  `00003000
DW  `00333300
DW  `00000000
; 2
DW  `00000000
DW  `00333300
DW  `03000030
DW  `00003300
DW  `00030000
DW  `00300000
DW  `03333330
DW  `00000000
; 3
DW  `00000000
DW  `00333300
DW  `03000030
DW  `00003300
DW  `00000030
DW  `03000030
DW  `00333300
DW  `00000000
; 4
DW  `00000000
DW  `00000300
DW  `00003300
DW  `00030300
DW  `00333300
DW  `00000300
DW  `00000300
DW  `00000000
; 5
DW  `00000000
DW  `03333330
DW  `03000000
DW  `00333300
DW  `00000030
DW  `03000030
DW  `00333300
DW  `00000000
; 6
DW  `00000000
DW  `00003000
DW  `00030000
DW  `00300000
DW  `03333300
DW  `03000030
DW  `00333300
DW  `00000000
; 7
DW  `00000000
DW  `03333330
DW  `00000300
DW  `00003000
DW  `00030000
DW  `00300000
DW  `00300000
DW  `00000000
; 8
DW  `00000000
DW  `00333300
DW  `03000030
DW  `00333300
DW  `03000030
DW  `03000030
DW  `00333300
DW  `00000000
 
; 9
DW  `00000000
DW  `00333300
DW  `03000030
DW  `03000030
DW  `00333300
DW  `00003000
DW  `00330000
DW  `03000000
 
; :
DW  `00000000
DW  `00033000
DW  `00033000
DW  `00000000
DW  `00033000
DW  `00033000
DW  `00000000
DW  `00000000
 
; empty tile
DW  `00000000
DW  `00000000
DW  `00000000
DW  `00000000
DW  `00000000
DW  `00000000
DW  `00000000
DW  `00000000
FinTiles:
